package com.bwie.service.impl;

import cn.hutool.core.util.IdUtil;
import com.bwie.common.constants.Constants;
import com.bwie.common.constants.JwtConstants;
import com.bwie.common.constants.TokenConstants;
import com.bwie.common.domain.User;
import com.bwie.common.domain.request.UserLoginReq;
import com.bwie.common.domain.response.UserLoginResp;
import com.bwie.common.exceptions.UserLoginExceptions;
import com.bwie.common.result.Result;
import com.bwie.common.utils.JwtUtils;
import com.bwie.common.utils.StringUtils;
import com.bwie.remote.RemoteSystemService;
import com.bwie.service.AuthService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @className: AuthServiceImpl
 * @Description: TODO
 * @version: v1.８.0
 * @author: 李明
 * @date: 2025/11/10 9:36
 */
@Service
public class AuthServiceImpl implements AuthService {

    //错误次数的键
    private static final String ERROR_COUNT_KEY = "error_count_key";
    //最大错误次数
    private static final Integer MAX_ERROR_COUNT = 5;

    @Autowired
    private RemoteSystemService remoteSystemService;

    @Autowired
    private BCryptPasswordEncoder bCryptPasswordEncoder;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Autowired
    private HttpServletRequest request;


    /**
     * 登录功能
     *
     * @param userLoginReq
     */
    @Override
    public UserLoginResp doLogin(UserLoginReq userLoginReq) {
        //获取数据
        String account = userLoginReq.getAccount();
        String password = userLoginReq.getPassword();
        //数据校验
        validateData(account,password);
        //通过账号获取用户信息
        Result<User> userInfo = remoteSystemService.getUserInfo(account);
        if (userInfo.getCode()==Constants.ERROR){
            throw new UserLoginExceptions(Constants.SYSTEM_ERROR_CODE,
                    Constants.SYSTEM_ERROR_MSG);
        }
        User user = userInfo.getData();
        if (null == user){
            throw new UserLoginExceptions(Constants.USER_BLANK_CODE,
                    Constants.USER_BLANK_MAG);
        }
        //密码加密
        //获取数据库中的密码
        String dbPassword = user.getPassword();
        boolean matches = bCryptPasswordEncoder.matches(password, dbPassword);
        //设置错误次数的键
        String errorCountKey = ERROR_COUNT_KEY + user.getPhone();
        if (!matches){
            Integer errorCount = (Integer) redisTemplate.opsForValue().get(errorCountKey);
            if (errorCount == null){
                errorCount = 0;
            }
            //错误次数加1
            errorCount++;
            //当错误次数大于5次时
            if (errorCount >= MAX_ERROR_COUNT){
                redisTemplate.opsForValue().set(errorCountKey, errorCount, 24, TimeUnit.HOURS);
                throw new UserLoginExceptions(Constants.PASSWORD_LOCK_CODE,
                        Constants.PASSWORD_LOCK_MSG);
            }else {
                //将剩余的错误次数润粗Redis中
                redisTemplate.opsForValue().set(errorCountKey, errorCount, 24, TimeUnit.HOURS);
                //剩余的错误次数为
                int remindCount = MAX_ERROR_COUNT - errorCount;
                String format = String.format(Constants.PASSWORD_LOGIN_ERROR_MSG + remindCount);
                throw new UserLoginExceptions(Constants.PASSWORD_LOGIN_ERROR_CODE, format);
            }
        }

        //生成token
        Map<String, Object> map = new HashMap<>();
        String userKey = IdUtil.simpleUUID();
        map.put(JwtConstants.USER_KEY, userKey);
        String token = JwtUtils.createToken(map);

        //将token存入redis中
        redisTemplate.opsForValue().set(TokenConstants.LOGIN_TOKEN_KEY + userKey,
                user, 30, TimeUnit.MINUTES);

        //创建UserLoginResp对象
        UserLoginResp userLoginResp = new UserLoginResp();
        userLoginResp.setToken(token);
        userLoginResp.setExpireTimeStr(Constants.EXPIRE_TIME);

        //删除错误次数的键值
        redisTemplate.delete(errorCountKey);

        //将数据响应给前端
        return userLoginResp;
    }

    /**
     * 获取登录人信
     */
    @Override
    public User getUser() {
        String token = request.getHeader(TokenConstants.TOKEN);
        String userKey = JwtUtils.getUserKey(token);
        User user = (User) redisTemplate.opsForValue().get(TokenConstants.LOGIN_TOKEN_KEY + userKey);
        return user;
    }


    /**
     * 数据参数校验
     * @param account
     * @param password
     */
    private void validateData(String account, String password) {
        if (StringUtils.isBlank(account)){
            throw new UserLoginExceptions(Constants.VALIDATE_DATA_BLANK_CODE,
                    Constants.VALIDATE_DATA_BLANK_MSG);
        }
        if (StringUtils.isBlank(password)){
            throw new UserLoginExceptions(Constants.VALIDATE_DATA_BLANK_CODE,
                    Constants.VALIDATE_DATA_BLANK_MSG);
        }
    }

    public static void main(String[] args) {
        BCryptPasswordEncoder cryptPasswordEncoder = new BCryptPasswordEncoder();
        String encode = cryptPasswordEncoder.encode("a123456");
        System.out.println(encode);
    }


}
